package com.study.mybatis;

import com.study.mybatis.dao.AnnotationUserDao;
import com.study.mybatis.dao.StudentDao;
import com.study.mybatis.dao.StudentDao2;
import com.study.mybatis.dao.UserDao;
import com.study.mybatis.dao.impl.StudentDaoImpl;
import com.study.mybatis.entity.Class;
import com.study.mybatis.entity.Monitor;
import com.study.mybatis.entity.Student;
import com.study.mybatis.entity.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import java.io.InputStream;
import java.util.List;

/**
 * @author wei.zhao
 * @date 2021年11月25日 14:22
 */
public class MybatisTest {

    SqlSessionFactory sessionFactory = null;

    @Before
    public void init() throws Exception {
        SqlSessionFactoryBuilder sessionFactoryBuilder = new SqlSessionFactoryBuilder();
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        sessionFactory = sessionFactoryBuilder.build(inputStream);
    }

    /*原始方式*/
    @Test
    public void test01() {
        StudentDao studentDao = new StudentDaoImpl(sessionFactory);
        //查询
        Student student = studentDao.findStudentById(1L);
        System.out.println(student);
        List<Student> students = studentDao.findStudentsByName("李四");
        System.out.println(students);
        //插入
        studentDao.insertStudent(Student.builder().name("哈哈哈").age(18).build());
    }

    /*Xml代理方式*/
    @Test
    public void test02() {
        SqlSession sqlSession = sessionFactory.openSession();
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        User user = userDao.findUserById(1L);
        System.out.println(user);
    }

    /*纯注解代理方式*/
    @Test
    public void test03() {
        SqlSession sqlSession = sessionFactory.openSession();
        //只有接口
        AnnotationUserDao annotationUserDao = sqlSession.getMapper(AnnotationUserDao.class);
        User user = annotationUserDao.findUserById(1L);
        System.out.println(user);
        //也有xml但是用的注解
        StudentDao2 studentDao2 = sqlSession.getMapper(StudentDao2.class);
        List<Student> students = studentDao2.queryAll();
        System.out.println(students);
    }

    /*普通一对一、一对多*/
    @Test
    public void test04() {
        SqlSession sqlSession = sessionFactory.openSession();
        StudentDao2 studentDao2 = sqlSession.getMapper(StudentDao2.class);
        Student student = studentDao2.oneToOne(1L);
        System.out.println(student);
        Class aClass = studentDao2.oneToMany(1L);
        System.out.println(aClass);
    }

    /*延迟加载一对一，一对多*/
    @Test
    public void test05() {
        SqlSession sqlSession = sessionFactory.openSession();
        StudentDao2 studentDao2 = sqlSession.getMapper(StudentDao2.class);
        Student student = studentDao2.oneToOneLazy(1L);
        System.out.println("============================");
        System.out.println(student);
        Class aClass = studentDao2.oneToManyLazy(1L);
        System.out.println("============================");
        System.out.println(aClass);
    }

    /*测试一级缓存*/
    @Test
    public void test06() {
        // true：自动提交，设置为true，只是为了让后面的数据进入到库中
        SqlSession sqlSession = sessionFactory.openSession(true);
        StudentDao2 dao = sqlSession.getMapper(StudentDao2.class);

        // 第一次查询ID为1的班级，去缓存找，找不到就去查找数据库并放入缓存
        Class aClass = dao.findClassById(1L);
        System.out.println(aClass);

        //同一个session执行增删改操作，清空缓存，不管是否提交
        dao.insertStudent(Student.builder().name("嘿嘿嘿").age(20).build());

        //不同session执行增删改操作，不清楚缓存
//        SqlSession sqlSession2 = sessionFactory.openSession();
//        StudentDao2 dao2 = sqlSession2.getMapper(StudentDao2.class);
//        dao2.insertStudent(Student.builder().name("哇哈哈").age(20).build());

        // 第二次查询ID为1的班级
        Class aClass2 = dao.findClassById(1L);
        System.out.println(aClass2);
    }

    /*测试二级缓存*/
    @Test
    public void test07() {
        SqlSession sqlSession1 = sessionFactory.openSession();
        SqlSession sqlSession2 = sessionFactory.openSession();
        SqlSession sqlSession3 = sessionFactory.openSession();
        StudentDao2 dao1 = sqlSession1.getMapper(StudentDao2.class);
        StudentDao2 dao2 = sqlSession2.getMapper(StudentDao2.class);
        StudentDao2 dao3 = sqlSession3.getMapper(StudentDao2.class);
        // 第一次查询ID为1的班级，去缓存找，找不到就去查找数据库
        Class aClass1 = dao1.findClassById(1L);
        System.out.println(aClass1);
        //当前session必须close或者commit，才会进入二级缓存
        sqlSession1.commit();

        //调用相同mapper中的增删改操作并commit，会清空缓存
        dao3.insertStudent2(Student.builder().name("嘿嘿嘿").age(20).build());
        sqlSession3.commit();
        //但是不知道为什么？如果是注解方式的增删改，不会清空缓存
        //dao3.insertStudent(Student.builder().name("嘿嘿嘿").age(20).build());
        //sqlSession3.commit();

        // 第二次查询ID为1的用户
        Class aClass2 = dao2.findClassById(1L);
        System.out.println(aClass2);
    }

    /*测试TypeHandler*/
    @Test
    public void test08() {
        SqlSession sqlSession = sessionFactory.openSession(true);
        StudentDao2 dao = sqlSession.getMapper(StudentDao2.class);
        /*插入*/
        dao.insertClass(Class.builder().name("高三一班").monitor(Monitor.builder().name("亮亮").age(30).build()).build());
        /*查询*/
        Class aClass = dao.queryClassById(4L);
        System.out.println(aClass);
    }

}
